package test.crane;

import ptolemy.actor.*;
import ptolemy.kernel.*;
import ptolemy.kernel.util.*;
import ptolemy.data.*;
import ptolemy.data.type.*;

//////////////////////////////////////////////////////////////////////////
//// ControlBrake
/**

@author Ivan Jeukens
@version v 0.1 07/02/2002
*/
public class ControlBrake extends TypedAtomicActor {

    public ControlBrake(CompositeEntity container, String name) throws
            IllegalActionException, NameDuplicationException {
        super(container, name);

        shutdown = new TypedIOPort(this, "shutdown", true, false);
        shutdown.setTypeEquals(BaseType.GENERAL);

        trigger = new TypedIOPort(this, "trigger", true, false);
        trigger.setTypeEquals(BaseType.GENERAL);

        emstop = new TypedIOPort(this, "emstop", true, false);
        emstop.setTypeEquals(BaseType.GENERAL);
        
        brake_in = new TypedIOPort(this, "brake_in", true, false);
        brake_in.setTypeEquals(BaseType.BOOLEAN);
        brake_in.setMultiport(true);
        
        posdesired = new TypedIOPort(this, "posdesired", true, false);
        posdesired.setTypeEquals(BaseType.DOUBLE);

        brake_out = new TypedIOPort(this, "brake_out", false, true);
        brake_out.setTypeEquals(BaseType.BOOLEAN);

        new Attribute(this, "_nonStrictMarker");
    }

    public TypedIOPort shutdown;
    public TypedIOPort trigger;
    public TypedIOPort emstop;
    public TypedIOPort brake_in;
    public TypedIOPort posdesired;
    public TypedIOPort brake_out;
    
    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////
    
    public void pruneDependencies() {
        super.pruneDependencies();
        removeDependency(trigger, brake_out);
        removeDependency(emstop, brake_out);
    }

    public void initialize() throws IllegalActionException {
        super.initialize();
        _reset();
    }

    public void fire() throws IllegalActionException {
        if(_state == RUNNING) {
            if(posdesired.isKnown() && shutdown.isKnown() && brake_in.isKnown() &&
                   !brake_out.isKnown()) {
            //if(posdesired.isKnown() && shutdown.isKnown() && brake_in.isKnown()) {

                boolean res = false;
                for(int i = 0;i < brake_in.getWidth();i++) {
                    if(brake_in.hasToken(i)) {
                        boolean b = ((BooleanToken)brake_in.get(i)).booleanValue();
                        if(b) {
                            res = true;
                        }
                    }
                }

                if(posdesired.hasToken(0)) {
                    _value = false;
                    System.out.println("Brake control -> has a posdesired");
                }

                if(res) {
                    _value = true;
                    System.out.println("Brake control -> alguma condicao de brake!");
                }

                if(shutdown.hasToken(0)) {
                    _value = true;
                   System.out.println("Brake control -> shutdown");
                }

                brake_out.broadcast(new BooleanToken(_value));
            }
        }
        else {
            brake_out.broadcast(new BooleanToken(_value));
        }
    }

    public boolean postfire() throws IllegalActionException {
        switch(_state) {

            case READY : {
                if(trigger.isKnown()) {
                    if(trigger.hasToken(0)) {
                        _state = RUNNING;
                        System.out.println("ControlBrake ativado!");
                    }
                }
            } break;
            
            case RUNNING : {
                if(shutdown.isKnown()) {
                    if(shutdown.hasToken(0)) {
                        _reset();
                        break;
                    }
                }

                if(emstop.isKnown()) {
                    if(emstop.hasToken(0)) {
                        _reset();
                        break;
                    }
                }
            } break;

        }

        return true;
    }
    
    ///////////////////////////////////////////////////////////////////
    ////                        private methods                    ////

    private void _reset() {
        _state = READY;
        _value = true;   // logo depois do sensor check, tem que dar o brake.
    }

    ///////////////////////////////////////////////////////////////////
    ////                      private variables                    ////

    private int _state;
    private boolean _value;

    private static final int READY = 1;
    private static final int RUNNING = 2;
}
